﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Persistencia.Repositorios;
using Entidades;
using Common;

namespace Controladores
{
    public class ControladorBase<T>  where T : Entidad
    {
        RepositorioBase<T> _repositorioBase = new RepositorioBase<T>();

        /// <summary>
        /// Devuelve la primer ocurrencia de la Entidad solicitada
        /// </summary>
        /// <param name="filtro"></param>
        /// <returns></returns>
        public T ObtenerEntidad()
        {
            try
            {
                return _repositorioBase.ObtenerEntidad();
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// Returns an Entity based on a given lambda expression as a filter (which will be transformed to a WHERE clause)
        /// </summary>
        /// <param name="expression"></param>
        /// <returns></returns>
        public T ObtenerEntidad(Func<T, bool> expression)
        {
            try
            {
                return _repositorioBase.ObtenerEntidad(expression);
            }
            catch (Exception)
            {
                throw;
            }        
        }

        /// <summary>
        /// Devuelve una Entidad, dado su Id (PK)
        /// </summary>
        /// <param name="filtro"></param>
        /// <returns></returns>
        public T ObtenerEntidad(int id)
        {
            try
            {
                return _repositorioBase.ObtenerEntidad(id);
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public List<T> ObtenerEntidades()
        {
            try
            {
                return _repositorioBase.ObtenerEntidades();
            }
            catch (Exception)
            {
                throw;
            }        
        }

        /// <summary>
        /// Devuelve la cantidad total de Entidades, según un filtro
        /// </summary>
        /// <param name="filtro"></param>
        /// <returns></returns>
        public int ObtenerTotalEntidades(string filtro)
        {
            try
            {
                return _repositorioBase.ObtenerTotalEntidades(filtro);
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// Devuelve la cantidad total de Entidades, según una expresión
        /// </summary>
        /// <param name="expression"></param>
        /// <returns></returns>
        public int ObtenerTotalEntidades(Func<T, bool> expression)
        {
            try
            {
                return _repositorioBase.ObtenerTotalEntidades(expression);
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// Devuelve una lista de todas las Entidades, según un filtro y paginación
        /// </summary>
        /// <param name="paginacion"></param>
        /// <param name="filtro"></param>
        /// <param name="sortColumn"></param>
        /// <param name="sortOrder"></param>
        /// <returns></returns>
        public List<T> ObtenerEntidades(Data.Pagination paginacion = null, string filtro = null, string sortColumn = "Id", string sortOrder = "asc")
        {
            var entidades = new List<T>();
            try
            {
                entidades = _repositorioBase.ObtenerEntidades(paginacion, filtro, sortColumn, sortOrder);
            }
            catch (Exception)
            {
                throw;
            }
            return entidades;
        }

        /// <summary>
        /// Returns an Entity based on a given lambda expression as a filter (which will be transformed to a WHERE clause)
        /// </summary>
        /// <param name="expression"></param>
        /// <returns></returns>
        public List<T> ObtenerEntidades(Func<T, bool> expression)
        {
            try
            {
                return _repositorioBase.ObtenerEntidades(expression);
            }
            catch (Exception)
            {
                throw;
            }        
        }

        /// <summary>
        /// Guarda una Entidad
        /// <param name="entidad"></param>
        /// </summary>
        /// <returns></returns>
        public bool GuardarEntidad(Entidad entidad)
        {
            try
            {
                return _repositorioBase.GuardarEntidad(entidad);
            }
            catch (Exception)
            {
                throw;
            }        
        }

        /// <summary>
        /// Elimina una Entidad
        /// </summary>
        /// <param name="entidad"></param>
        /// <returns></returns>
        public bool EliminarEntidad(Entidad entidad)
        {
            return _repositorioBase.EliminarEntidad(entidad);
        }

        /// <summary>
        /// Elimina una Entidad
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public bool EliminarEntidad(int id)
        {
            return _repositorioBase.EliminarEntidad(id);
        }
   
        /// <summary>
        /// Elimina una lista de Entidades, de una entidad, según una condicion
        /// </summary>
        /// <param name="filtro"></param>
        /// <returns></returns>
        public bool EliminarEntidades(Type entidad, string condicion)
        {
            try
            {
                return _repositorioBase.EliminarEntidades(entidad, condicion);
            }
            catch (Exception)
            {
                throw;
            }
        }

        #region Stored Procedure

        public class StoredProcedure
        {
            public int GetTotalRecords(string sp, Dictionary<string, object> parameters = null)
            {
                var totalRecords = new RepositorioBase<Entidades.Calculado.TotalRecords>.StoredProcedure().GetList(sp, parameters);
                return totalRecords.Any() ? (int)totalRecords[0].Count : 0;
            }
            public T GetObject(string sp, Dictionary<string, object> parameters = null)
            {
                return new RepositorioBase<T>.StoredProcedure().GetObject(sp, parameters);
            }
            public IList<T> GetList(string sp, Dictionary<string, object> parameters = null)
            {
                return new RepositorioBase<T>.StoredProcedure().GetList(sp, parameters);
            }
            public IList<T> GetList(string sp, int pageSize, int currentPage, Dictionary<string, object> parameters = null)
            {
                return new RepositorioBase<T>.StoredProcedure().GetList(sp, pageSize, currentPage, parameters);
            }
        }

        #endregion
    }
}